#!/usr/bin/env python
"""
启动脚本：快速启动整个调度系统
"""
import os
import sys
import subprocess
import time
import threading
import socket
from pathlib import Path

# 确保能导入 Django
sys.path.insert(0, str(Path(__file__).parent))
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'django_scheduler.settings')

import django
django.setup()

from django.core.management import call_command
from utils.task_service import TaskService
from example_tasks import simple_task, calculate_task, random_task


def get_machine_ips():
    """获取机器的所有IP地址"""
    ips = {
        'localhost': '127.0.0.1',
        'internal': None,
        'external': None,
        'all_interfaces': []
    }
    
    try:
        # 方法1: 获取主要内网IP
        with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
            s.connect(("8.8.8.8", 80))
            internal_ip = s.getsockname()[0]
            ips['internal'] = internal_ip
    except:
        pass
    
    try:
        # 方法2: 获取hostname对应的IP
        hostname = socket.gethostname()
        hostname_ip = socket.gethostbyname(hostname)
        if hostname_ip != '127.0.0.1' and not hostname_ip.startswith('169.254'):
            ips['all_interfaces'].append(hostname_ip)
    except:
        pass
    
    try:
        # 方法3: 尝试获取所有本地IP地址
        import platform
        if platform.system() == 'Linux':
            # Linux系统使用ip命令
            result = subprocess.run(['hostname', '-I'], capture_output=True, text=True, timeout=5)
            if result.returncode == 0:
                for ip in result.stdout.strip().split():
                    if ip != '127.0.0.1' and not ip.startswith('169.254'):
                        ips['all_interfaces'].append(ip)
        elif platform.system() == 'Windows':
            # Windows系统使用ipconfig
            result = subprocess.run(['ipconfig'], capture_output=True, text=True, timeout=5)
            if result.returncode == 0:
                import re
                ip_pattern = r'IPv4.*?: (\d+\.\d+\.\d+\.\d+)'
                for match in re.finditer(ip_pattern, result.stdout):
                    ip = match.group(1)
                    if ip != '127.0.0.1' and not ip.startswith('169.254'):
                        ips['all_interfaces'].append(ip)
    except:
        pass
    
    # 确保内网IP在列表中
    if ips['internal'] and ips['internal'] not in ips['all_interfaces']:
        ips['all_interfaces'].insert(0, ips['internal'])
    
    # 去重保持顺序
    ips['all_interfaces'] = list(dict.fromkeys(ips['all_interfaces']))
    
    return ips


def update_django_settings(ips):
    """动态更新Django设置以允许外部访问"""
    settings_file = Path(__file__).parent / 'django_scheduler' / 'settings.py'
    
    try:
        # 读取现有设置
        with open(settings_file, 'r', encoding='utf-8') as f:
            content = f.read()
        
        # 准备ALLOWED_HOSTS列表
        allowed_hosts = ['localhost', '127.0.0.1']
        
        # 添加所有找到的IP
        for ip in ips['all_interfaces']:
            if ip not in allowed_hosts:
                allowed_hosts.append(ip)
        
        if ips['external']:
            allowed_hosts.append(ips['external'])
        
        # 添加通配符以支持动态IP
        allowed_hosts.append('*')  # 生产环境中应该更具体
        
        # 构建新的ALLOWED_HOSTS行
        new_allowed_hosts = f"ALLOWED_HOSTS = {allowed_hosts}"
        
        # 替换ALLOWED_HOSTS设置
        import re
        pattern = r"ALLOWED_HOSTS\s*=\s*\[.*?\]"
        if re.search(pattern, content):
            content = re.sub(pattern, new_allowed_hosts, content)
        else:
            # 如果没找到，在DEBUG设置后添加
            debug_pattern = r"(DEBUG\s*=\s*.*?)\n"
            content = re.sub(debug_pattern, f"\\1\n\n{new_allowed_hosts}\n", content)
        
        # 写回文件
        with open(settings_file, 'w', encoding='utf-8') as f:
            f.write(content)
        
        print(f"✅ 已更新ALLOWED_HOSTS: {allowed_hosts}")
        return True
        
    except Exception as e:
        print(f"⚠️  更新Django设置失败: {e}")
        return False


def run_migrations():
    """运行数据库迁移"""
    print("🔧 运行数据库迁移...")
    try:
        # 先为app应用创建迁移
        call_command('makemigrations', 'app', verbosity=1)
        # 运行所有迁移
        call_command('migrate', verbosity=1)
        print("✅ 数据库迁移完成")
        return True
    except Exception as e:
        print(f"❌ 数据库迁移失败: {e}")
        return False


def create_superuser():
    """创建超级用户（如果不存在）"""
    print("👤 检查超级用户...")
    try:
        from django.contrib.auth.models import User
        if not User.objects.filter(is_superuser=True).exists():
            print("创建默认超级用户 (admin/admin123)...")
            User.objects.create_superuser('admin', 'admin@example.com', 'admin123')
            print("✅ 超级用户创建完成")
        else:
            print("✅ 超级用户已存在")
        return True
    except Exception as e:
        print(f"❌ 超级用户创建失败: {e}")
        return False


def create_example_tasks():
    """创建示例任务"""
    print("📋 创建示例任务...")
    try:
        task_service = TaskService()
        
        # 创建示例任务
        tasks = [
            {
                'name': '简单任务 - 每分钟执行',
                'description': '每分钟执行一次的简单任务，用于测试基本功能',
                'module_path': 'example_tasks',
                'function_name': 'simple_task',
                'trigger_type': 'interval',
                'trigger_config': {'minutes': 1},
                'is_active': True
            },
            {
                'name': '计算任务 - 每5分钟',
                'description': '每5分钟执行一次的计算任务',
                'module_path': 'example_tasks',
                'function_name': 'calculate_task',
                'args': [10, 5],
                'kwargs': {'operation': 'multiply'},
                'trigger_type': 'interval',
                'trigger_config': {'minutes': 5},
                'is_active': True
            },
            {
                'name': '随机任务 - 每2分钟',
                'description': '随机成功/失败的任务，用于测试错误处理',
                'module_path': 'example_tasks',
                'function_name': 'random_task',
                'trigger_type': 'interval',
                'trigger_config': {'minutes': 2},
                'is_active': True
            },
            {
                'name': '数据库备份 - 每天凌晨2点',
                'description': '每天凌晨2点执行数据库备份',
                'module_path': 'example_tasks',
                'function_name': 'database_backup_task',
                'trigger_type': 'cron',
                'trigger_config': {'hour': 2, 'minute': 0},
                'is_active': False  # 默认不启用
            },
            {
                'name': '清理日志 - 每周日凌晨3点',
                'description': '每周日凌晨3点清理30天前的日志',
                'module_path': 'example_tasks',
                'function_name': 'cleanup_logs_task',
                'kwargs': {'days_old': 30},
                'trigger_type': 'cron',
                'trigger_config': {'day_of_week': 0, 'hour': 3, 'minute': 0},
                'is_active': False  # 默认不启用
            },
            {
                'name': '系统健康检查 - 每30分钟',
                'description': '每30分钟执行一次系统健康检查',
                'module_path': 'example_tasks',
                'function_name': 'system_health_check_task',
                'trigger_type': 'interval',
                'trigger_config': {'minutes': 30},
                'is_active': True
            }
        ]
        
        # 检查是否已经有任务
        from app.models import ScheduledTask
        if ScheduledTask.objects.exists():
            print("✅ 示例任务已存在，跳过创建")
            return True
        
        created_count = 0
        for task_config in tasks:
            try:
                task = task_service.create_scheduled_task(**task_config)
                print(f"  ✓ 创建任务: {task.name}")
                created_count += 1
            except Exception as e:
                print(f"  ✗ 创建任务失败 '{task_config['name']}': {e}")
        
        print(f"✅ 成功创建 {created_count} 个示例任务")
        return True
        
    except Exception as e:
        print(f"❌ 创建示例任务失败: {e}")
        return False


def start_django_server(port=8005):
    """启动 Django 开发服务器"""
    print("🌐 正在启动 Django 开发服务器...")
    
    # 获取机器IP地址
    ips = get_machine_ips()
    
    # 更新Django设置
    update_django_settings(ips)
    
    # 显示所有可访问的地址
    print("\n📍 服务器访问地址:")
    print(f"   本地访问: http://127.0.0.1:{port}")
    
    if ips['internal']:
        print(f"   内网访问: http://{ips['internal']}:{port}")
    
    for ip in ips['all_interfaces']:
        if ip != ips['internal']:
            print(f"   网络访问: http://{ip}:{port}")
    
    print(f"\n📊 管理界面路径: /admin (admin/admin123)")
    print(f"🔗 API 接口路径: /api")
    
    # 显示防火墙提示
    print(f"\n⚠️  网络访问提示:")
    print(f"   1. 确保防火墙开放 {port} 端口")
    print(f"   2. 如果是云服务器，检查安全组设置")
    print(f"   3. 生产环境建议使用nginx反向代理")
    
    print(f"\n🚀 正在启动Django服务器 (0.0.0.0:{port})...")
    
    try:
        # 实际启动Django服务器
        call_command('runserver', f'0.0.0.0:{port}', verbosity=1)
        return True
    except Exception as e:
        print(f"❌ Django服务器启动失败: {e}")
        return False


def start_scheduler():
    """启动调度器"""
    print("⏰ 启动任务调度器...")
    try:
        from utils.scheduler_manager import SchedulerManager
        
        scheduler_manager = SchedulerManager()
        scheduler_manager.start_scheduler()
        
        print("✅ 任务调度器已启动")
        
        # 显示调度器状态
        status = scheduler_manager.get_scheduler_status()
        print(f"📊 调度器状态: {'运行中' if status['running'] else '已停止'}")
        print(f"📋 活跃任务数: {status['job_count']}")
        
        return True
        
    except Exception as e:
        print(f"❌ 调度器启动失败: {e}")
        return False


def print_system_info(port=8005):
    """打印系统信息"""
    ips = get_machine_ips()
    
    print("\n" + "=" * 70)
    print("🎉 Django APScheduler 任务调度系统启动完成!")
    print("=" * 70)
    print("\n📋 可用功能:")
    print("  • 任务调度和管理")
    print("  • 异步任务执行")
    print("  • 实时监控和日志")
    print("  • REST API 接口")
    print("  • Web 管理界面")
    
    print("\n🌐 系统访问地址:")
    
    # 本地访问
    print(f"  📱 本地访问:")
    print(f"     • 管理界面: http://127.0.0.1:{port}/admin")
    print(f"     • API 接口: http://127.0.0.1:{port}/api")
    
    # 内网访问
    if ips['internal']:
        print(f"  🏠 内网访问:")
        print(f"     • 管理界面: http://{ips['internal']}:{port}/admin")
        print(f"     • API 接口: http://{ips['internal']}:{port}/api")
    
    # 其他网络接口
    other_ips = [ip for ip in ips['all_interfaces'] if ip != ips['internal']]
    if other_ips:
        print(f"  🌐 网络访问:")
        for ip in other_ips:
            print(f"     • 管理界面: http://{ip}:{port}/admin")
            print(f"     • API 接口: http://{ip}:{port}/api")
    
    # 公网访问
    if ips['external']:
        print(f"  🌍 公网访问 (需要防火墙开放):")
        print(f"     • 管理界面: http://{ips['external']}:{port}/admin")
        print(f"     • API 接口: http://{ips['external']}:{port}/api")
    
    print(f"\n👤 登录信息: admin / admin123")
    
    print("\n📖 主要 API 端点:")
    print("  • GET  /api/tasks/              - 获取任务列表")
    print("  • POST /api/tasks/              - 创建新任务")
    print("  • GET  /api/scheduler/status/   - 调度器状态")
    print("  • GET  /api/logs/               - 执行日志")
    print("  • POST /api/async-tasks/submit/ - 提交异步任务")
    
    print("\n🔧 管理命令:")
    print(f"  • python manage.py runserver 0.0.0.0:{port}    - 启动Web服务")
    print("  • python manage.py start_scheduler            - 启动调度器")
    print("  • python manage.py scheduler_status           - 查看状态")
    
    print("\n🔒 网络安全提示:")
    print(f"  • 防火墙开放端口: {port}")
    print("  • 云服务器检查安全组")
    print("  • 生产环境使用HTTPS")
    print("  • 修改默认密码")
    
    print("\n⚠️  使用 Ctrl+C 停止系统")
    print("=" * 70)


def main():
    """主启动函数"""
    # 获取命令行参数
    port = 8005
    if len(sys.argv) > 1:
        try:
            port = int(sys.argv[1])
        except ValueError:
            print("⚠️  端口号必须是数字，使用默认端口 8005")
    
    print("🚀 正在启动 Django APScheduler 任务调度系统...")
    print(f"🔧 服务端口: {port}")
    print("=" * 60)
    
    # 步骤0: 显示当前机器信息
    ips = get_machine_ips()
    print("📍 检测到的IP地址:")
    if ips['internal']:
        print(f"   内网IP: {ips['internal']}")
    for ip in ips['all_interfaces']:
        print(f"   网卡IP: {ip}")
    if ips['external']:
        print(f"   公网IP: {ips['external']}")
    print()
    
    # 步骤1: 运行数据库迁移
    if not run_migrations():
        print("❌ 系统启动失败：数据库迁移失败")
        sys.exit(1)
    
    # 步骤2: 创建超级用户
    if not create_superuser():
        print("❌ 系统启动失败：超级用户创建失败")
        sys.exit(1)
    
    # 步骤3: 创建示例任务
    if not create_example_tasks():
        print("❌ 系统启动失败：示例任务创建失败")
        sys.exit(1)
    
    # 步骤4: 启动调度器（先启动，后台运行）
    if not start_scheduler():
        print("❌ 系统启动失败：调度器启动失败")
        sys.exit(1)
    
    # 显示系统信息
    print_system_info(port)
    
    # 步骤5: 启动 Django 服务器（最后启动，前台运行）
    print("\n" + "=" * 60)
    print("🚀 最后步骤：启动Django Web服务器...")
    print("=" * 60)
    
    if not start_django_server(port):
        print("❌ 系统启动失败：Django 服务器启动失败")
        sys.exit(1)


if __name__ == '__main__':
    main()